package com.bolehui.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bolehui.base.result.Result;
import com.bolehui.base.utils.DateUtil;
import com.bolehui.base.utils.LogUtil;
import com.bolehui.base.utils.MinioUtil;
import com.bolehui.base.utils.SecurityUtil;
import com.bolehui.base.utils.uuid.IdUtils;
import com.bolehui.config.MinioConfig;
import com.bolehui.domain.dto.FileDTO;
import com.bolehui.domain.po.FilePO;
import com.bolehui.mapper.UploadMapper;
import com.bolehui.service.UploadService;
import io.minio.MinioClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author chendongjie     email:chendongjie@gz.iscas.ac.cn
 * @version 1.0
 * @ClassName uploadSterviceImpl
 * @Description
 * @createTime 2024/12/2 11:01
 * Copyright (C) 2021-2022 CASEEDER, All Rights Reserved.
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 */
@Service
public class UploadServiceImpl extends ServiceImpl<UploadMapper, FilePO> implements UploadService {

    @Autowired
    private UploadMapper uploadMapper;

    @Autowired
    private MinioUtil minioUtil;
    @Autowired
    private MinioClient minioClient;
    @Autowired
    private MinioConfig prop;

    /**
     * 允许上传文件扩展名白名单
     */
    @Value("${upload.accept-ext:pdf}")
    private String acceptFileExtensions;

    /**
     * 上传简历
     *
     * @return
     */
    @Override
    public Result upload(MultipartFile file, Long id) {
        if (file.getOriginalFilename() == null) {
            return null;
        }
        // 仅支持pdf文件上传
        String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1);
        if (!StringUtils.equalsAnyIgnoreCase(fileExt, acceptFileExtensions)) {
            LogUtil.warn(String.format("文件上传 上传文件[%s]的类型为[%s]，当前应用不支持", file.getOriginalFilename(), fileExt));
            return Result.fail("不支持该文件类型");
        }
        if (id == null) {
            return Result.fail("用户不存在");
        }
        String fileName = minioUtil.upload(file);
        if (StringUtils.isEmpty(fileName)) {
            return Result.fail("上传失败");
        }
        Long fileSize = file.getSize();
        FilePO filePO = FilePO.builder()
                .fileName(fileName)
                .fileSize(fileSize)
                .userId(id)
                .build();
        this.saveOrUpdate(filePO, new QueryWrapper<FilePO>().eq("user_id", id));
        return Result.success();
    }

    /**
     * 查询文件
     *
     * @return
     */
    @Override
    public Result queryResume(Long id) {
        if (id == null) {
            return Result.fail("用户不存在");
        }
        LambdaQueryWrapper<FilePO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(FilePO::getUserId, id);
        FilePO resume = uploadMapper.selectOne(wrapper);

        if (ObjectUtil.isNull(resume)) {
            return Result.fail("用户未上传简历");
        }

        String fileName = resume.getFileName();
        // 获取文件名称，过滤多余的前缀
        Pattern pattern = Pattern.compile(".*[/\\\\]([^/\\\\]+)$"); // 匹配最后一个斜杠后的任意字符直到字符串末尾
        Matcher matcher = pattern.matcher(fileName);
        if (matcher.find()) {
            fileName = matcher.group(1); // 获取匹配到的文件名部分
        }
        return Result.success(fileName);
    }

    /**
     * 删除文件
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteResume(Long id) throws Exception {
        FilePO filePO = uploadMapper.selectById(id);
        if (Objects.isNull(filePO)) {
            Result.fail("文件不存在");
        }

        String fileName = filePO.getFileName();
        int i = uploadMapper.deleteById(id);
        if (i == 0) {
            LogUtil.warn(String.format("数据库文件删除失败:%s", fileName));
            return Result.fail("文件删除失败");
        }

        boolean remove = minioUtil.remove(fileName);
        if (!remove) {
            LogUtil.warn(String.format("minio文件删除失败:%s", fileName));
            throw new Exception(String.format("minio文件删除失败:%s", fileName));
        }
        return Result.success();
    }

    /**
     * 文件预览
     *
     * @param id
     * @return
     */
    @Override
    public Result previewImage(Long id) throws UnsupportedEncodingException {
        FilePO filePO = uploadMapper.selectOne(new QueryWrapper<FilePO>().eq("user_id", id));
        if (Objects.isNull(filePO)) {
            return Result.fail("文件不存在");
        }
        String fileName = filePO.getFileName();
        return Result.success(fileName);
    }
}
